package net.xinshi.controller;

import com.alibaba.fastjson.JSON;
import net.xinshi.boot.AppConfig;
import net.xinshi.domain.ApiJsonRequest;
import net.xinshi.domain.JSONResponseObj;
import net.xinshi.domain.JsonResponseObject;
import net.xinshi.exception.ApiException;
import net.xinshi.model.*;
import net.xinshi.service.business.IApiService;
import net.xinshi.utils.BeanUtils;
import net.xinshi.utils.ErrorCode;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

/**
 * @author <a href="mailto:liukuo@xinshi.net">liukuo</a>
 * @version 1.0
 * @description
 * @since 2017/6/29.
 */
@RestController
@RequestMapping("/apiadmin/")
public class ApiAdminController extends AbstractRestController {
    private static final Logger LOGGER = LogManager.getLogger(ApiAdminController.class);
    @Autowired
    private IApiService apiService;
    @Autowired
    private AppConfig appConfig;

    @RequestMapping(value = "/list", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public JSONResponseObj getApiList(@RequestBody ApiJsonRequest req) {
        LOGGER.info("请求获取API分页查询,请求参数是:" + JSON.toJSONString(req));
        try {
            checkToken(req);

            ApiPageInputDTO input = BeanUtils.beanCopy(req, ApiPageInputDTO.class);
            BasePageOutputDTO<ApiOutputDTO> output = apiService.queryApiList(input);

            JSONResponseObj res = new JSONResponseObj();
            res.setCode(output.getCode());
            res.setMsg(output.getMsg());
            res.setData(output);
            return res;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("请求获取API分页查询，code: {}, msg: {}", ErrorCode.ERR_UNKNOWN_ERROR.getCode(),
                    e.getMessage());
            if (e instanceof ApiException) {
                ApiException ex = (ApiException) e;
                return new JSONResponseObj(ex.getCode(), ex.getMessage());
            }
            return new JSONResponseObj(ErrorCode.ERR_UNKNOWN_ERROR.getCode(), ErrorCode.ERR_UNKNOWN_ERROR.getMsg());
        }
    }

    @RequestMapping(value = "/add", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public JSONResponseObj addApi(@RequestBody ApiJsonRequest req) {
        LOGGER.info("请求增加API,请求参数是:" + JSON.toJSONString(req));
        try {
            checkToken(req);

            ApiInputDTO input = BeanUtils.beanCopy(req, ApiInputDTO.class);
            if (input == null) {
                throw new ApiException(ErrorCode.ERR_REST_INPUT_VALIDATION_REJECTED, ErrorCode.ERR_REST_INPUT_VALIDATION_REJECTED.getMsg());
            }
            if (StringUtils.isBlank(input.getApiId())) {
                throw new ApiException(ErrorCode.ERR_API_IS_REQUIRE, ErrorCode.ERR_API_IS_REQUIRE.getMsg());
            }
            if (StringUtils.isBlank(input.getApiName())) {
                throw new ApiException(ErrorCode.ERR_APP_NAME_IS_REQUIRE, ErrorCode.ERR_APP_NAME_IS_REQUIRE.getMsg());
            }
            if (StringUtils.isBlank(input.getApiUrl())) {
                throw new ApiException(ErrorCode.ERR_APP_URL_IS_REQUIRE, ErrorCode.ERR_APP_URL_IS_REQUIRE.getMsg());
            }
            if (input.getApiState() == null) {
                input.setApiState(0);
            }
            if (StringUtils.isBlank(input.getApiSys())) {
                input.setApiSys("");
            }
            if (StringUtils.isBlank(input.getContent())) {
                input.setContent("");
            }
            //保存api之后调用刷新api接口的方法
            int id = apiService.saveApi(input);

            apiService.refreshApi();

            JSONResponseObj res = new JSONResponseObj();
            res.setCode(ErrorCode.SUCCESS.getCode());
            res.setMsg(ErrorCode.SUCCESS.getMsg());
            return res;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("请求获取API分页查询，code: {}, msg: {}", ErrorCode.ERR_UNKNOWN_ERROR.getCode(),
                    e.getMessage());
            if (e instanceof ApiException) {
                ApiException ex = (ApiException) e;
                return new JSONResponseObj(ex.getCode(), ex.getMessage());
            }
            return new JSONResponseObj(ErrorCode.ERR_UNKNOWN_ERROR.getCode(), ErrorCode.ERR_UNKNOWN_ERROR.getMsg());
        }
    }

    @RequestMapping(value = "/update", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public JSONResponseObj update(@RequestBody ApiJsonRequest req) {
        LOGGER.info("请求增加API,请求参数是:" + JSON.toJSONString(req));
        try {
            checkToken(req);

            ApiInputDTO input = BeanUtils.beanCopy(req, ApiInputDTO.class);
            if (input == null) {
                throw new ApiException(ErrorCode.ERR_REST_INPUT_VALIDATION_REJECTED, ErrorCode.ERR_REST_INPUT_VALIDATION_REJECTED.getMsg());
            }
            if (StringUtils.isBlank(input.getApiId())) {
                throw new ApiException(ErrorCode.ERR_API_IS_REQUIRE, ErrorCode.ERR_API_IS_REQUIRE.getMsg());
            }
            if (StringUtils.isBlank(input.getApiName())) {
                throw new ApiException(ErrorCode.ERR_APP_NAME_IS_REQUIRE, ErrorCode.ERR_APP_NAME_IS_REQUIRE.getMsg());
            }
            if (StringUtils.isBlank(input.getApiUrl())) {
                throw new ApiException(ErrorCode.ERR_APP_URL_IS_REQUIRE, ErrorCode.ERR_APP_URL_IS_REQUIRE.getMsg());
            }

            //修改api之后，调用更新api列表的方法
            int id = apiService.updateApi(input);
            apiService.refreshApi();

            JSONResponseObj res = new JSONResponseObj();
            res.setCode(ErrorCode.SUCCESS.getCode());
            res.setMsg(ErrorCode.SUCCESS.getMsg());
            return res;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("请求获取API分页查询，code: {}, msg: {}", ErrorCode.ERR_UNKNOWN_ERROR.getCode(),
                    e.getMessage());
            if (e instanceof ApiException) {
                ApiException ex = (ApiException) e;
                return new JSONResponseObj(ex.getCode(), ex.getMessage());
            }
            return new JSONResponseObj(ErrorCode.ERR_UNKNOWN_ERROR.getCode(), ErrorCode.ERR_UNKNOWN_ERROR.getMsg());
        }
    }

    @RequestMapping(value = "/get", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public JSONResponseObj getApi(@RequestBody @Valid ApiJsonRequest req) {
        LOGGER.info("请求获取API接口,请求参数是:" + JSON.toJSONString(req));
        try {
            checkToken(req);

            if (req.getId() == null) {
                return new JSONResponseObj(ErrorCode.ERR_REST_INPUT_VALIDATION_REJECTED.getCode(), ErrorCode.ERR_REST_INPUT_VALIDATION_REJECTED.getMsg());
            }
            BaseIdInputDTO input = BeanUtils.beanCopy(req, BaseIdInputDTO.class);
            ApiOutputDTO output = apiService.queryApi(input);
            LOGGER.info("查询结果是:" + JSON.toJSONString(output));
            JSONResponseObj res = new JSONResponseObj();
            res.setCode(ErrorCode.SUCCESS.getCode());
            res.setMsg(ErrorCode.SUCCESS.getMsg());
            res.setData(output);
            LOGGER.info("返回数据," + JSON.toJSONString(res));
            return res;
        } catch (Exception e) {
            LOGGER.error("请求获取API接口，code: {}, msg: {}", ErrorCode.ERR_UNKNOWN_ERROR.getCode(), e.getMessage());
            if (e instanceof ApiException) {
                ApiException ex = (ApiException) e;
                return new JSONResponseObj(ex.getCode(), ex.getMessage());
            }
            return new JSONResponseObj(ErrorCode.ERR_UNKNOWN_ERROR.getCode(), ErrorCode.ERR_UNKNOWN_ERROR.getMsg());
        }
    }

    @RequestMapping(value = "/delete", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public JSONResponseObj delete(@RequestBody @Valid ApiJsonRequest req) {
        LOGGER.info("请求删除API接口,请求参数是:" + JSON.toJSONString(req));
        try {
            checkToken(req);

            if (req.getId() == null) {
                return new JSONResponseObj(ErrorCode.ERR_REST_INPUT_VALIDATION_REJECTED.getCode(), ErrorCode.ERR_REST_INPUT_VALIDATION_REJECTED.getMsg());
            }
            BaseIdInputDTO input = BeanUtils.beanCopy(req, BaseIdInputDTO.class);
            Integer count = apiService.deleteApi(input);
            //删除api之后调用刷新api列表的方法
            apiService.refreshApi();
            JSONResponseObj res = new JSONResponseObj();
            if (count > 0) {
                res.setCode(ErrorCode.SUCCESS.getCode());
                res.setMsg(ErrorCode.SUCCESS.getMsg());
            } else {
                res.setCode(ErrorCode.ERR_DATA_OPER_ERROR.getCode());
                res.setMsg(ErrorCode.ERR_DATA_OPER_ERROR.getMsg());
            }
            LOGGER.info("返回数据," + JSON.toJSONString(res));
            return res;
        } catch (Exception e) {
            LOGGER.error("请求获取API接口，code: {}, msg: {}", ErrorCode.ERR_UNKNOWN_ERROR.getCode(), e.getMessage());
            if (e instanceof ApiException) {
                ApiException ex = (ApiException) e;
                return new JSONResponseObj(ex.getCode(), ex.getMessage());
            }
            return new JSONResponseObj(ErrorCode.ERR_UNKNOWN_ERROR.getCode(), ErrorCode.ERR_UNKNOWN_ERROR.getMsg());
        }
    }

    @RequestMapping(value = "/refreshApi", method = RequestMethod.GET)
    @ResponseBody
    public JsonResponseObject refreshApi() {
        LOGGER.info("刷新API列表");
        try {
            apiService.refreshApi();
            LOGGER.info("刷新API列表成功");
            JsonResponseObject res = new JsonResponseObject();
            return res;
        } catch (Exception e) {
            LOGGER.error("刷新API列表，code: {}, msg: {}", ErrorCode.ERR_UNKNOWN_ERROR.getCode(), e.getMessage());
            e.printStackTrace();
            return new JsonResponseObject(ErrorCode.ERR_UNKNOWN_ERROR.getCode(), ErrorCode.ERR_UNKNOWN_ERROR.getMsg());
        }
    }

    private void checkToken(ApiJsonRequest req){
        if (req == null) {
            throw new ApiException(ErrorCode.ERR_REST_INPUT_VALIDATION_REJECTED, ErrorCode.ERR_REST_INPUT_VALIDATION_REJECTED.getMsg());
        }
        if (!StringUtils.equals(req.getToken(), appConfig.getLogToken())) {
            throw new ApiException("E000001", "你无权限进行此操作");
        }
    }
}
